package com.xasz.text2vec.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xasz.text2vec.dao.entity.DaySearch;
import com.xasz.text2vec.dao.entity.DaySum;
import com.xasz.text2vec.dao.mapper.DaySearchMapper;
import com.xasz.text2vec.dao.mapper.DaySumMapper;
import com.xasz.text2vec.service.DaySumService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xasz.text2vec.utils.Cal_sta;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.chrono.ChronoLocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author cai
 * @since 2023-07-07
 */
@Service
public class DaySumServiceImpl extends ServiceImpl<DaySumMapper, DaySum> implements DaySumService {

    @Autowired
    private DaySearchMapper daySearchMapper;
    @Autowired
    private DaySumMapper daySumMapper;
    @Override
    public boolean statByDay() {
        //统计今天的查询日志
        QueryWrapper<DaySearch> queryWrapper=new QueryWrapper<DaySearch>();
        queryWrapper.between("create_time",LocalDate.now().plusDays(-1),LocalDate.now());
        List<DaySearch> daySearches = daySearchMapper.selectList(queryWrapper);
        //统计数量
        HashMap<String,Integer> map = new HashMap<>();
        for (DaySearch daySearch:daySearches){
            map.merge(daySearch.getQCatgory(), 1, Integer::sum);
        }
        //保存统计结果
        map.forEach((k,v) -> {
            DaySum daySum=new DaySum();
            daySum.setCategory(k);
            daySum.setSum(v);
            daySumMapper.insert(daySum);
        });
        return true;
    }

    @Override
    public boolean analyseByDay() {
        //获取有相关关系的列表
        Set<Set<String>> analyse = analyse();
        //获取当天sum
        QueryWrapper<DaySum> queryWrapper=new QueryWrapper<DaySum>();
        queryWrapper.select("category","sum")
                .between("create_time",LocalDate.now().plusDays(-1),LocalDate.now());
        List<DaySum> daySums = daySumMapper.selectList(queryWrapper);
        //todo 循环当天sum查看是否有异常
        for (DaySum daySum:daySums){

        }

        return false;
    }

    /**
     * 获取有相关关系的列表
     */
    public Set<Set<String>> analyse() {
        //查询所有sum
        QueryWrapper<DaySum> queryWrapper=new QueryWrapper<DaySum>();
        queryWrapper.select("category","sum","create_time");
        List<DaySum> daySums = daySumMapper.selectList(queryWrapper);

        //获取每一个分类的数列map集合
        HashMap<String, List<Double>> map = getMap(daySums);

        Set<Set<String>> set = new HashSet<>();
        //遍历每一个分类判断俩俩间是否有关系
        int i=map.size();
        map.forEach((k1,v1)->{
            map.forEach((k2,v2)->{
                //不是同一个,判断是否有关系
                if (!Objects.equals(k1, k2)){
                    //计算相关性
                    Double correlation = getCorrelation(v1, v2);
                    if (correlation>0.8 || correlation<-0.8){
                        //有相关性:去重
                        Set<String> set1 = new HashSet<>();
                        set1.add(k1);
                        set1.add(k2);
                        set.add(set1);
                    } else if (correlation<0.3 && correlation>-0.3 ) {
                        //System.out.println(k1+"和"+k2+"无关:"+correlation);
                    }else{
                        //System.out.println(k1+"和"+k2+"不确定有相关性:"+correlation);
                    }
                }
            });
        });
        System.out.println(set);
        return set;
    }

    /**
     * 计算两个数列相关性
     */
    public Double getCorrelation(List<Double> list1,List<Double> list2){
        Cal_sta calSta=new Cal_sta();
        List<List<Double>> list=new ArrayList<>();
        list.add(list1);
        list.add(list2);
        return calSta.correlation(list);
    }

    /**
     *获取参与计算的时间范围
     */
    public List<LocalDate> getTime(List<DaySum> daySums){
        //按照时间分开
        Map<LocalDate, List<DaySum>> timeResult = daySums.stream().collect(Collectors.groupingBy(data->data.getCreateTime().toLocalDate()));
        //获取时间范围
        List<LocalDate> time=new ArrayList<>();
        timeResult.forEach((k,v)->{
            time.add(k);
        });
        Collections.reverse(time);
        return  time;
    }

    /**
     *获取传入实体的按类型时间分类
     */
    public HashMap<String,List<Double>> getMap(List<DaySum> daySums){
        //获取参与计算的时间范围
        List<LocalDate> time=getTime(daySums);

        //按照分类把数据分开
        Map<String, List<DaySum>> categoryResult = daySums.stream().collect(Collectors.groupingBy(DaySum::getCategory));
        //获取数据的分类范围
        List<String> category=new ArrayList<>();
        categoryResult.forEach((k,v)->{
            category.add(k);
        });

        HashMap<String,List<Double>> map = new HashMap<>();
        for (String cate:category){
            //保存每个分类的sum值列表
            List<Double> doubles=new ArrayList<>();
            for (LocalDate localDate:time){
                List<DaySum> daySums1 = categoryResult.get(cate);
                //找到对应的实体数据
                List<DaySum> daySumStream = daySums1.stream()
                        .filter(str -> localDate.isEqual(ChronoLocalDate.from(str.getCreateTime())))
                        .collect(Collectors.toList());
                //取sum值,没有默认为0.0
                double sum=0.0;
                if (daySumStream.size()!=0){
                    DaySum daySum = daySumStream.get(0);
                    sum= daySum.getSum();
                }
                doubles.add(sum);
            }
            map.put(cate,doubles);
        }
        return map;
    }

}
